package com.campus.lostandfound.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.lostandfound.entity.User;
import com.campus.lostandfound.entity.UserRole;
import com.campus.lostandfound.mapper.UserMapper;
import com.campus.lostandfound.mapper.UserRoleMapper;
import com.campus.lostandfound.service.UserService;
import com.campus.lostandfound.utils.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

/**
 * 用户Service实现类
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean register(User user) {
        // 检查用户名是否已存在
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, user.getUsername())
               .or()
               .eq(User::getPhone, user.getPhone());
        
        if (count(wrapper) > 0) {
            throw new RuntimeException("用户名或手机号已存在");
        }
        
        // 检查学号/工号是否已存在
        if (StringUtils.isNotBlank(user.getStudentNo())) {
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getStudentNo, user.getStudentNo());
            if (count(wrapper) > 0) {
                throw new RuntimeException("学号/工号已存在");
            }
        }
        
        // 生成用户ID和盐值
        user.setUserId(UUID.randomUUID().toString().replace("-", ""));
        String salt = MD5Util.generateSalt();
        user.setSalt(salt);
        
        // 加密密码
        String encryptedPassword = MD5Util.encryptWithSalt(user.getPassword(), salt);
        user.setPassword(encryptedPassword);
        
        // 设置默认值
        if (user.getRole() == null) {
            user.setRole(0); // 默认为普通用户
        }
        user.setStatus(1); // 正常状态
        user.setViolationCount(0);
        
        // 保存用户到 user 表
        boolean saved = save(user);
        
        if (saved) {
            // 自动为新用户分配默认的"普通用户"角色（role_id = 3，对应 USER 角色）
            try {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId()); // 使用保存后生成的 ID
                userRole.setRoleId(3L);           // USER 角色的 ID
                userRoleMapper.insert(userRole);
            } catch (Exception e) {
                // 如果分配角色失败，记录日志但不影响注册
                System.err.println("为新用户分配默认角色失败: " + e.getMessage());
            }
        }
        
        return saved;
    }
    
    @Override
    public User login(String username, String password) {
        // 查询用户
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username)
               .or()
               .eq(User::getPhone, username);
        
        User user = getOne(wrapper);
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 检查账号状态
        if (user.getStatus() == 0) {
            throw new RuntimeException("账号已被禁用");
        }
        
        // 验证密码
        String encryptedPassword = MD5Util.encryptWithSalt(password, user.getSalt());
        if (!encryptedPassword.equals(user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        return user;
    }
    
    @Override
    @Cacheable(value = "user", key = "#userId", unless = "#result == null")
    public User getUserByUserId(String userId) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUserId, userId);
        System.out.println("【缓存】从数据库查询用户信息: " + userId);
        return getOne(wrapper);
    }
    
    @Override
    @CacheEvict(value = "user", key = "#userId")
    public boolean changePassword(String userId, String oldPassword, String newPassword) {
        User user = getUserByUserId(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证旧密码
        String encryptedOldPassword = MD5Util.encryptWithSalt(oldPassword, user.getSalt());
        if (!encryptedOldPassword.equals(user.getPassword())) {
            throw new RuntimeException("原密码错误");
        }
        
        // 生成新密码
        String newSalt = MD5Util.generateSalt();
        String encryptedNewPassword = MD5Util.encryptWithSalt(newPassword, newSalt);
        
        user.setSalt(newSalt);
        user.setPassword(encryptedNewPassword);
        
        System.out.println("【缓存】清除用户缓存: " + userId);
        return updateById(user);
    }
    
    @Override
    public User getUserByPhone(String phone) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone);
        
        User user = getOne(wrapper);
        if (user == null) {
            throw new RuntimeException("该手机号未注册");
        }
        
        return user;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetPasswordByPhone(String phone, String newPassword) {
        // 通过手机号查询用户
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, phone);
        
        User user = getOne(wrapper);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 生成新的盐值和加密密码
        String newSalt = MD5Util.generateSalt();
        String encryptedPassword = MD5Util.encryptWithSalt(newPassword, newSalt);
        
        user.setSalt(newSalt);
        user.setPassword(encryptedPassword);
        
        return updateById(user);
    }
}

